using FastDevTemplate.Common.Util;
using FastDevTemplate.DataAccess;
using FastDevTemplate.DataAccess.Entities;
using FastDevTemplate.Service.Base;
using FastDevTemplate.Service.Interface;
using FastDevTemplate.Service.Interface.DTO;
using Microsoft.EntityFrameworkCore;

namespace FastDevTemplate.Service;

public class RoleService(FastDevTemplateDbContext dbContext) :
    BaseCurdService<Role, string, RoleResultDto, RoleGetResultDto, RoleAddDto, RoleModifyDto>(dbContext),
    IRoleService
{
    public async Task<int> AddPermissionListAsync(string id, params string[] permissionIDs)
    {
        //check:
        var entity = await EntityFindAsync(id);
        if (entity == null)
            return ErrorHandling(ErrorType.LogicNotFindEntityError, nameof(AddPermissionListAsync));

        //logic:
        await using var transaction = await Dao.Database.BeginTransactionAsync();
        foreach (var pk in permissionIDs)
                entity.AddPermission(pk);
        DbSet.Update(entity);

        //Error Handle:
        try
        {
            var count = await Dao.SaveChangesAsync();
            await transaction.CommitAsync();
            return count > 0 ? count : ErrorHandling(ErrorType.DataBaseSaveError, nameof(AddPermissionListAsync));
        }
        catch (Exception e)
        {
            await transaction.RollbackAsync();
            return ErrorHandling(ErrorType.DataBaseSaveError, e);
        }
    }
    
    public async Task<int> RemovePermissionListAsync(string id, params string[] permissionIDs)
    {
        //Check:
        var entity = await EntityFindAsync(id);
        if (entity == null)
            return ErrorHandling(ErrorType.LogicNotFindEntityError, nameof(AddPermissionListAsync));

        //logic:
        await using var transaction = await Dao.Database.BeginTransactionAsync();
        foreach (var pk in permissionIDs)
                entity.RemovePermission(pk);
        DbSet.Update(entity);

        //Error Handle:
        try
        {
            var count = await Dao.SaveChangesAsync();
            await transaction.CommitAsync();
            return count > 0 ? count : ErrorHandling(ErrorType.DataBaseSaveError, nameof(AddPermissionListAsync));
        }
        catch (Exception e)
        {
            await transaction.RollbackAsync();
            return ErrorHandling(ErrorType.DataBaseSaveError, e);
        }
    }
    
    public async Task<int> SetPermissionListAsync(string id, params string[] permissionIDs)
    {
        //Check:
        var entity = await EntityFindAsync(id);
        if (entity == null)
            return ErrorHandling(ErrorType.LogicNotFindEntityError, nameof(AddPermissionListAsync));
        
        //logic:
        await using var transaction = await Dao.Database.BeginTransactionAsync();
        entity.SetPermission(permissionIDs);
        DbSet.Update(entity);
        
        //Error Handle:
        try
        {
            var count = await Dao.SaveChangesAsync();
            await transaction.CommitAsync();
            return count > 0 ? count : ErrorHandling(ErrorType.DataBaseSaveError, nameof(AddPermissionListAsync));
        }
        catch (Exception e)
        {
            await transaction.RollbackAsync();
            return ErrorHandling(ErrorType.DataBaseSaveError, e);
        }
    }
    
    public override string GenerateKey(Role entity)
    {
        return entity.ID;
    }

    protected override async ValueTask<Role?> EntityFindAsync(string id)
    {
        return await DbSet.Include(item => item.RolePermissions).FirstOrDefaultAsync(item => item.ID == id);
    }
}